/**
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package br.biofoco.p2p.rpc.multicast;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import org.apache.log4j.Logger;

import br.biofoco.p2p.rpc.EndPoint;
import br.biofoco.p2p.rpc.Protocol;
import br.biofoco.p2p.rpc.messaging.CommandHandler;
import br.biofoco.p2p.rpc.messaging.Transport;
import br.biofoco.p2p.rpc.messaging.TransportClient;

public class MulticastServer implements Transport {
	
	private MulticastSocket socket;
	private String address;
	private volatile boolean isStarted = false;
	
	private int port;
	
	public MulticastServer(String address, int port) {
		this.address = address;
		this.port = port;
	}
	
	private static final Logger LOGGER = Logger.getLogger(MulticastServer.class);
	private MulticastListener listener;
	
	public void setListener(MulticastListener listener) {
		this.listener = listener;
	}
	
	public void start() throws IOException {
		socket = new MulticastSocket(port);
        socket.joinGroup(InetAddress.getByName(address));
        
        Thread t = new Thread(new ServerListener());
        t.start();
        
        LOGGER.debug("Server started");
        
        isStarted = true;
	}
		
	public void sendMessage(String message) throws IOException {
		LOGGER.debug("Sending multicast message");
		byte[] buffer = new byte[65535];
		DatagramPacket packet = new DatagramPacket(buffer, buffer.length);		
		socket.send(packet);
	}
	
	private class ServerListener implements Runnable {

		@Override
		public void run() {
			LOGGER.debug("Starting multicast listener on port " + port);
			try {
				while (isStarted) {
					byte[] buffer = new byte[65535];
					DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
					socket.receive(packet);
					LOGGER.debug("Multicast message received");
					if (listener != null)
						listener.onMessage(new String(buffer).trim());
				}
			} catch (IOException e) {
				e.printStackTrace();
			}			
		}		
	}

	@Override
	public TransportClient createClient(EndPoint endpoint) throws Exception {
		throw new UnsupportedOperationException("Operation not supported!");
	}

	@Override
	public Protocol getProtocol() {
		return Protocol.UDP_MCAST;
	}

	@Override
	public boolean isActive() {
        return isStarted;
	}

	@Override
	public void setCommandHandler(CommandHandler handler) {
		throw new UnsupportedOperationException("Operation not supported");
		
	}

	@Override
	public void stop() throws Exception {
		throw new UnsupportedOperationException("Operation not supported");
	}

}
